旧游无处不堪寻
无寻处,惟有少年心
『计算机的组成与设计』-处理器

程序必须首先让人类可以理解,然后顺便让机器能执行。

前面几篇我们说过,一台计算机的性能有三个关键因素决定: 指令数目时钟周期长度每条指令所需要的时钟周期数 CPI
编译器和指令集决定了一个程序所需的指令数目,而处理器则决定了时钟周期长度和 CPI。
本篇通过一个基本 MIPS 实现,来了解实现一个处理器所需要的原理和技术。

基本 MIPS 实现


  • 访存指令: lw 和 sw
  • 运算指令: add,sub,AND,OR 和 slt
  • 分支指令: beq 和 j

实现方式概述

通过之前几篇的叙述,我们知道要实现的这几个简单指令的实现过程大致相同,与具体指令无关。
实现每条指令的前两步是一样的:

  1. 程序计数器(PC)指向指令所在的储存单元,从中取出指令。
  2. 通过指令,读取一个或两个寄存器。对于取字指令,只需读取一个寄存器,其他大多数指令需要读取两个寄存器。

这两步之后的步骤取决于具体的指令类型,详见建立数据通路的基本原则

处理器的设计步骤


  1. 分析指令系统,得出对数据通路的需求
  2. 为数据通路选择合适的组件
  3. 连接组件建立数据通路
  4. 分析每条指令的实现,以确定控制信号
  5. 集成控制信号,形成完整的控制逻辑

指令的含义


指令位域的分解

对于R型指令,可以分为 6 个位域。最高的 6bit 称为操作码,接下来三个位域都是 5 个 bit,标识寄存器,接下来一个 5bit,用来标识移位。最后 6bit 是功能位域。
I型指令,可分解 3 个位域。最高的 6bit 称为操作码,接下来两个个位域都是 5 个 bit,标识寄存器,最后 16bit 是立即数位域。

指令系统的需求

  • 算术逻辑单元(ALU)
  1. 算术类型: 加,减,或,比较等
  2. 操作数: 2 个 32 位的数,来自寄存器或扩展后的立即数
  • 立即数扩展部件
  1. 将一个 16 位的立即数扩展为 32 位
  2. 扩展方式: 0 扩展,符号扩展
  • 程序计数器(PC)
  1. 1 个 32 位寄存器
  2. 支持两种加法: 加 4 或加一个立即数
  • 寄存器堆(两读一写寄存器堆,register file)
  1. 每个寄存器为 32 位宽,共 32 个
  2. 支持读操作: rs 或 rt
  3. 支持写操作: rd 或 rt
  • 存储器(对应 CPU 内部的 cache 而不是整个计算机的 memory)
  1. 1 个只读的指令存储器,地址和数据均是 32 位
  2. 1 个可读写的数据存储器,地址和数据均是 32 位

建立数据通路的基本原则


根据指令需求,连接组件,建立数据通路
指令需求分为:

  1. 所有指令的共同需求
  2. 不同指令的不同需求

所有指令的共同需求


  1. 取指令
  • PC 的内容就是指令的地址
  • 用 PC 的内容作为地址,访问指令存储器获取指令编码
  1. 更新 PC
  • 顺序执行: PC = PC + 4
  • 发生分支: PC = 分支目标地址

不同指令的不同需求


流水线(pipelining)


流水线是一种实现多条指令重叠执行的技术。
流水线的奇妙之处在于,当处理多个任务的时候,每个任务的总处理时间并没有缩短,但所有的工作都在并行进行,因此,单位时间能够完成的工作量就大大增加了。流水线实际改善了吞吐率。如果所有的步骤所需的时间一样,那么从流水线得到的速度提高倍数等于流水线中步骤的数目。